<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>

    <!-- 卡片 -->
    <el-card>
      <!-- 添加角色按钮 -->
      <el-row>
        <el-col>
          <el-button type="primary">添加角色</el-button>
        </el-col>
      </el-row>
      <!-- 角色列表区域 -->
      <el-table :data="roleList" style="width: 100%">
        <!-- 展开列 -->
        <el-table-column type="expand">
          <template slot-scope="scope">
            <!-- 遍历当前角色的 一级权限 -->
            <el-row
              :class="['bottonBorder', ind1 == 0 ? 'topBorder' : '', 'vcenter']"
              v-for="(item1, ind1) in scope.row.children"
              :key="item1.id"
            >
              <!-- 第一列 放 一级权限-->
              <el-col :span="5">
                <el-tag closable @close="delRightById(scope.row, item1.id)">{{
                  item1.authName
                }}</el-tag>
                <!-- 一级图标 -->
                <i class="el-icon-caret-right"></i>
              </el-col>
              <!--第二列 二级和三级 -->
              <el-col :span="19">
                <!-- 第二列中放一个行 -->
                <el-row
                  :class="[ind2 == 0 ? '' : 'topBorder', 'vcenter']"
                  v-for="(item2, ind2) in item1.children"
                  :key="item2.id"
                >
                  <!-- 行中第一列 -->
                  <el-col :span="6">
                    <el-tag
                      type="danger"
                      closable
                      @close="delRightById(scope.row, item2.id)"
                    >
                      {{ item2.authName }}
                    </el-tag>
                    <!-- 二级图标 -->
                    <i class="el-icon-caret-right"></i>
                  </el-col>
                  <!-- 行中第二列 -->
                  <el-col :span="18">
                    <el-tag
                      closable
                      @close="delRightById(scope.row, item3.id)"
                      type="warning"
                      v-for="item3 in item2.children"
                      :key="item3.id"
                    >
                      {{ item3.authName }}
                    </el-tag>
                  </el-col>
                </el-row>
              </el-col>
            </el-row>
          </template>
        </el-table-column>
        <el-table-column type="index" label="#"> </el-table-column>
        <el-table-column prop="roleName" label="角色名"> </el-table-column>
        <el-table-column prop="roleDesc" label="说明"> </el-table-column>

        <el-table-column label="操作">
          <template slot-scope="scope">
            <!-- 修改按钮 -->
            <el-button type="primary" icon="el-icon-edit" size="mini"
              >编辑</el-button
            >
            <!-- 删除按钮 -->
            <el-button type="danger" icon="el-icon-delete" size="mini"
              >删除</el-button
            >
            <!-- 分配角色按钮 -->
            <el-tooltip effect="dark" content="分配角色">
              <el-button
                type="warning"
                icon="el-icon-setting"
                size="mini"
                @click="ShowRightDialog(scope.row)"
              >
                分配权限</el-button
              >
            </el-tooltip>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <!-- 分配权限对话框 -->
    <el-dialog
      title="提示"
      :visible.sync="isShowRightDialog"
      width="50%"
      @close="closeRightDialog"
    >
      <!-- 树形结构菜单 -->
      <el-tree
        :data="treeList"
        :props="treeProps"
        show-checkbox
        default-expand-all
        node-key="id"
        :default-checked-keys="checkedKeys"
        ref="rightTree"
      >
      </el-tree>
      <!-- 按钮区域 -->
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowRightDialog = false">取 消</el-button>
        <el-button type="primary" @click="setRoleRights">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  created() {
    this.getRoleList()
  },
  data() {
    return {
      //角色 表格数据数组
      roleList: [],
      //权限 树形菜单数据数组
      treeList: [],
      //树形菜单 配置对象
      treeProps: {
        //用来作为 字菜单数组 读取的属性名
        // children: 'children',
        //用来作为 菜单文本 显示的属性名
        label: 'authName',
      },
      //是否显示 分配权限 对话框
      isShowRightDialog: false,
      //树形菜单 默认选中项 的 id
      checkedKeys: [142],
      //当前选中的 角色id
      roleId: 0,
    }
  },
  methods: {
    // 获取角色列表
    async getRoleList() {
      // 异步请求 角色列表
      const { data: resData } = await this.$http.get('roles')
      // 如果获取失败,显示错误提示
      if (resData.meta.status !== 200) {
        return this.$message.error(resData.meta.msg)
      }
      // 将返回的 角色数组 设置给 roleList
      this.roleList = resData.data
    },
    // 根据Id删除权限
    delRightById(roleData, rightId) {
      // 确认是否要删除
      this.$messageBox.confirm('确定要删除吗', '系统提示', {
        confirmButtonText: '确定',
        callback: async (action) => {
          // 如果点击的是取消按钮 则 停止执行函数
          if (action == 'cancel') return
          // 如果点击确认按钮 根据id请求 服务器删除权限接口
          const { data: resData } = await this.$http.delete(
            `roles/${roleData.id}/rights/${rightId}`
          )
          // 判断删除结果 如果失败 提示错误
          if (resData.meta.status !== 200) {
            return this.$message.error(resData.meta.msg)
          }
          // 如果成功 则更新视图 中的 角色权限
          // 将 当前行数据的权限数组 换成 接口返回的 新的权限数组
          // 由于数组发生改变 所以 视图会重新 渲染 这个角色的权限列表
          roleData.children = resData.data
        },
      })
    },
    // 打开分配权限 窗口
    async ShowRightDialog(rowData) {
      //请求 所有 权限列表（树形结构）
      let { data: resData } = await this.$http.get('rights/tree')
      //如果获取数据失败
      if (resData.meta.status !== 200) this.$message.error(resData.meta.msg)
      //如果成功 则数据 设置给 treeList 数组 用来渲染 树形菜单
      this.treeList = resData.data

      //将 当前角色 拥有的 权限设置为 选中转态
      //将 当前角色 一级权限 数组 传入
      this.getRightIds(rowData.children)
      //显示 分配权限 窗口
      this.isShowRightDialog = true
      //将 角色id保存到 data中 等 点击 确认分配权限时 再使用
      this.roleId = rowData.id
    },
    //获取所有 三级权限id 并传入 checkedKeys数组
    //rightList权限数组
    //目标：将判断为三级权限 的id加入 checkedKeys数组
    //思路： 将传入的数组 元素 判断一下 是否有 children 属性
    //      如果有则 遍历children属性
    //      直到 遇见 没有 children属性的元素
    getRightIds(rightList) {
      // a.遍历 传入的 数组
      rightList.forEach((ele) => {
        //b. 判断当前权限 对象 是否有 children 属性
        if (ele.children) {
          // b1. 如果有 children 属性 则说明 不是三级权限 需要递归遍历
          this.getRightIds(ele.children)
        } else {
          // b2 如果 没有 children  则说明是 三级权限  将id直接存给checkedKeys数组
          this.checkedKeys.push(ele.id) //加入到这个数组里边的权限id 对应的权限节点 都会被选中
        }
      })
    },
    // 关闭窗口的时候 清空数组
    closeRightDialog() {
      this.checkedKeys = []
    },
    //确定分配 角色 权限 按钮点击事件方法
    async setRoleRights() {
      //1.可以通过 this.roleId 获取 当前 要修改权限的 角色id
      //2.获取 选中的 权限id 并转成 分隔的字符串
      let a = this.$refs.rightTree.getCheckedKeys()
      let b = this.$refs.rightTree.getHalfCheckedKeys()
      //将 获取的 全选 和半选中 权限 的 id 组成一个 新数组
      let rightIds = [...a, ...b]
      //3. 将 新权限的 id 以 , 分隔 的方式 组成一个 字符串
      let strIds = rightIds.join(',')
      //4.发送请求 到 服务器接口 更新 角色权限
      let { data: resData } = await this.$http.post(
        `roles/${this.roleId}/rights`,
        {
          rids: strIds,
        }
      )
      //5.如果 请求失败 则提示
      if (resData.meta.status !== 200)
        return this.$message.error(resData.meta.msg)
      //6.如果请求成功  则重新 请求 整个 角色视图数据
      this.$message.success(resData.meta.msg)
      this.getRoleList()
      //7.关闭当前对话框
      this.isShowRightDialog = false
    },
  },
}
</script>
<style lang="less" scoped>
.el-tag {
  margin: 7px;
}
.topBorder {
  border-top: 1px solid #eee;
}
.bottonBorder {
  border-bottom: 1px solid #eee;
}

.vcenter {
  display: flex;
  align-items: center;
}
</style>
